import { ActionTree, ActionContext } from 'vuex';
import { UserActionTypes, UserMutationTypes } from './types';
import { RootState } from '@/store';
import { UserState } from './state';
import { Mutations } from './mutations';
import { loginRequest, logoutRequest } from '@/apis/user';
import { resetRouter } from '@/router';
import {
  setToken,
  removeToken,
  setUserName,
  removeUserName,
} from '@/utils/cookies';

type UserInfoType = {
  userName: string,
  password: string,
}

type AugmentedActionContext = {
  commit<K extends keyof Mutations>(
    key: K,
    payload: Parameters<Mutations[K]>[1],
  ): ReturnType<Mutations[K]>
} & Omit<ActionContext<UserState, RootState>, 'commit'>

export interface Actions {
  [UserActionTypes.ACTION_LOGIN](
    { commit }: AugmentedActionContext,
    userInfo: UserInfoType,
  ): void,
  [UserActionTypes.ACTION_GET_USER_INFO](
    { commit }: AugmentedActionContext
  ): void,
  [UserActionTypes.ACTION_LOGIN_OUT](
    { commit }: AugmentedActionContext,
  ): void,
}

export const actions: ActionTree<UserState, RootState> & Actions = {
  [UserActionTypes.ACTION_LOGIN](
    { commit }: AugmentedActionContext, userInfo: UserInfoType,
  ) {
    let { userName } = userInfo;
    const { password } = userInfo;
    userName = userName.trim();
    return new Promise((resovle, reject) => {
      loginRequest({ userName, password }).then(async (res: any) => {
        if (res.status === '0' && res.data && res.data.token) {
          const { token, userDetail: { user } } = res.data;
          setToken(token);
          setUserName(user.userName);
          commit(UserMutationTypes.SET_TOKEN, token);
          commit(UserMutationTypes.SET_NAME, user.userName);
          resovle({});
        } else {
          reject(new Error());
        }
      }).catch(() => {
        reject();
      });
    });
  },
  [UserActionTypes.ACTION_GET_USER_INFO]({ commit }: AugmentedActionContext) {
    commit(UserMutationTypes.SET_ROLES, ['admin']);
  },
  [UserActionTypes.ACTION_LOGIN_OUT]({ commit }: AugmentedActionContext) {
    return new Promise((resovle, reject) => {
      logoutRequest().then((res: any) => {
        if (res.status === '0') {
          // 清除 cookie 中的 token、username
          removeToken();
          removeUserName();
          // 清除 store
          commit(UserMutationTypes.SET_TOKEN, '');
          commit(UserMutationTypes.SET_NAME, '');
          commit(UserMutationTypes.SET_ROLES, []);
          // 重置路由
          resetRouter();
          resovle({});
        } else {
          reject(new Error());
        }
      }).catch(() => {
        reject(new Error());
      });
    });
  },
};
